using System;
using System.Diagnostics;
using System.Threading;

namespace ViewOn.Helper.Memory
{

	/// <summary>
	/// Take a look at this article for explaination.
	/// http://www.coversant.net/dotnetnuke/Coversant/Blogs/tabid/88/EntryID/4/Default.aspx
	/// </summary>
	public static class MemoryHelper
	{

		private static volatile bool _enabled = true;
		private static Timer _timer;
		private static AutoResetEvent _autoEvent = new AutoResetEvent(false);

		/// <summary>
		/// Running this code causes Windows to free up as much of the working set as possible.
		/// Usually this sends most of your bloat to the page file where it will remain forever.
		/// </summary>
		public static void Start()
		{
			_timer = new Timer(new TimerCallback(CheckMemory),
								_autoEvent,
								30000,
								30000);
		}

		static public void Stop()
		{
			_timer.Change(Timeout.Infinite, Timeout.Infinite);
		}

		static public void CheckMemory(Object stateInfo)
		{
			FakeOutTheUserToThinkWeDontUseAnyMemory();
		}

		/// <summary>
		/// Running this code causes Windows to free up as much of the working set as possible.
		/// Usually this sends most of your bloat to the page file where it will remain forever.
		/// </summary>
		private static void FakeOutTheUserToThinkWeDontUseAnyMemory()
		{

			if (!_enabled)
				return;

			try
			{
                System.Diagnostics.Process curProc = System.Diagnostics.Process.GetCurrentProcess();
				curProc.MaxWorkingSet = curProc.MaxWorkingSet;
			}

			catch
			{
				// Some users won't have permission to adjust their working set.
				_enabled = false;

				// When autoEvent signals the second time, dispose of 
				// the timer.
				_autoEvent.WaitOne(5000, false);
				_timer.Dispose();
			}
		}

	}
}
